package edu.uwm.cs552;

import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;

import edu.uwm.cs552.util.Pair;


public class HexEdge implements HasTopography<Barrier> {
	
	public static final HexEdge ORIGIN = new HexEdge(HexCoordinate.ORIGIN, HexDirection.EAST);
	
	private HexCoordinate hexCoordinate;
	private HexDirection hexDirection;
	
	private Barrier barrier;

	public HexEdge(HexCoordinate hc, HexDirection hd) {
		hexCoordinate = hc;
		hexDirection = hd;
	}
	
	public double a() {
		double a = hexCoordinate.a() + (double)hexDirection.da()/2;		
		return a;
	}
	
	public double b() {
		double b = hexCoordinate.b() + (double)hexDirection.db()/2;
		return b;
	}
	
	public boolean equals(Object obj) {
		if(obj == null || !(obj instanceof HexEdge))
			return false;
		
		if(Double.compare(a(), ((HexEdge)obj).a()) == 0 && Double.compare(b(), ((HexEdge)obj).b()) == 0)
			return true;
		return false;
	}
	
	public int hashCode() {
		return (int)(a() * 17 + b() * 16777619);
	}
	
	public String toString() {
		return hexCoordinate.toString() + "@" + hexDirection.toString();
	}
	
	public static HexEdge fromString(String edge) {
		if(edge == null)
			return null;
			
		int index = edge.indexOf('@');
		HexCoordinate hc = HexCoordinate.fromString(edge.substring(0, index));
		HexDirection hd = HexDirection.valueOf(edge.substring(index+1));
		return new HexEdge(hc, hd);
	}
	
	private static final double THIRD = 1.0/3.0;
	private static final double TWOTHIRDS = 2.0/3.0;
	
	public Pair<Point, Point> toLineSegment(double scale) {
		
		Point p1, p2;
		
		switch(hexDirection) {
			case NORTHEAST: p1 = HexCoordinate.toPoint(hexCoordinate.a()-THIRD,hexCoordinate.b()-TWOTHIRDS,scale);
			   				p2 = HexCoordinate.toPoint(hexCoordinate.a()+THIRD,hexCoordinate.b()-THIRD,scale);
			   				break;
			case EAST: p1 = HexCoordinate.toPoint(hexCoordinate.a()+THIRD,hexCoordinate.b()-THIRD,scale); 
					   p2 = HexCoordinate.toPoint(hexCoordinate.a()+TWOTHIRDS,hexCoordinate.b()+THIRD,scale); 
					   break;
			case SOUTHEAST: p1 = HexCoordinate.toPoint(hexCoordinate.a()+TWOTHIRDS,hexCoordinate.b()+THIRD,scale);
							p2 = HexCoordinate.toPoint(hexCoordinate.a()+THIRD,hexCoordinate.b()+TWOTHIRDS,scale);
							break;
			case SOUTHWEST: p1 = HexCoordinate.toPoint(hexCoordinate.a()+THIRD,hexCoordinate.b()+TWOTHIRDS,scale);
							p2 = HexCoordinate.toPoint(hexCoordinate.a()-THIRD,hexCoordinate.b()+THIRD,scale);
							break;
			case WEST: p1 = HexCoordinate.toPoint(hexCoordinate.a()-THIRD,hexCoordinate.b()+THIRD,scale); 
					   p2 = HexCoordinate.toPoint(hexCoordinate.a()-TWOTHIRDS,hexCoordinate.b()-THIRD,scale); 
					   break;
			case NORTHWEST: p1 = HexCoordinate.toPoint(hexCoordinate.a()-TWOTHIRDS,hexCoordinate.b()-THIRD,scale);
							p2 = HexCoordinate.toPoint(hexCoordinate.a()-THIRD,hexCoordinate.b()-TWOTHIRDS,scale);
							break;
			default: p1 = new Point(0,0);
					 p2 = new Point(0,0);
					 break;
		}
		
		return new Pair<Point, Point>(p1, p2);
	}
	
	@Override
	public void draw(Graphics g, double scale, boolean showHidden) {
		if(barrier == Barrier.DRAWN)
			barrier.draw(g, this, scale, showHidden);
		if(showHidden)
			barrier.draw(g, this, scale, showHidden);
	}
	
	private static final double SQRT32 = Math.sqrt(3.0)/2.0;
	
	public static HexEdge fromPoint(Point point, double scale) {
		HexCoordinate hc = HexCoordinate.fromPoint(point, scale);
		Point hexPoint = hc.toPoint(scale);
		
		double b1 = hexPoint.getY() / SQRT32;
		double b2 = point.getY() / SQRT32;
		
		double a1 = hexPoint.getX() + b1 / 2.0;
		double a2 = point.getX() + b2 / 2.0;
		
		HexDirection hd = HexDirection.fromDelta((a2 - a1), (b2 - b1));
		return new HexEdge(hc, hd);
	}

	@Override
	public Barrier getTopography() {
		return barrier;
	}

	@Override
	public void setTopography(Barrier topography) {
		this.barrier = topography;
	}

	@Override
	public Point toPoint(double scale) {
		return null;
	}

	@Override
	public Polygon toPolygon(double scale) {
		return null;
	}

	@Override
	public HasTopography<Barrier> move(HexDirection d) {
		return null;
	}
}
	
